const regex = /(\{|\})/gi;
const regex1A = /(\{(?!\w)|\}(?!\w))/gi;

const commonJSFormatter = ({ token, darkTheme, isVR }) => {
  const isWebMappingToken = token.filePath.includes('mapping');

  return JSON.stringify({
    name:
      isVR && !isWebMappingToken
        ? token.path.join('-').replace('appenda', '')
        : token.path.join('-').replace('appenda', '').replace('appendb', ''),
    value: token.value,
    // For lightened values with appended 1A, let's keep {value}1A if not remove the parenthesis

    // eslint-disable-next-line no-nested-ternary
    originalValue: isVR
      ? 'NA'
      : // eslint-disable-next-line no-nested-ternary
      typeof token.original.value === 'string'
      ? token.original.value.endsWith('}1A')
        ? token.original.value?.replace(regex1A, '')
        : token.original.value.replace(regex, '')
      : token.value,
    // eslint-disable-next-line no-underscore-dangle
    ...(darkTheme ? { _darkModeSupport: !token._darkMode } : {}), // For dark mode we are adding this metadada to track unsupported tokens
    comment: token.comment,
    category: token.attributes.category,
  });
};

const moduleExportFileHeader = ({ file, tokenArray, fileHeader }) =>
  `${fileHeader({ file, commentStyle: 'short' })} module.exports = [${tokenArray}]`;

// register web formats
function registerWebFormats(sd) {
  const { fileHeader } = sd.formatHelpers;

  sd.registerFormat({
    name: 'commonJS/classic',
    formatter: ({ dictionary, file }) => {
      const tokenArray = dictionary.allTokens.map((token) => commonJSFormatter({ token }));
      return moduleExportFileHeader({ fileHeader, file, tokenArray });
    },
  });

  sd.registerFormat({
    name: 'commonJS/vr-theme',
    formatter: ({ dictionary, file }) => {
      const tokenArray = dictionary.allTokens.map((token) =>
        commonJSFormatter({ token, isVR: true }),
      );
      return moduleExportFileHeader({ fileHeader, file, tokenArray });
    },
  });

  sd.registerFormat({
    name: 'darkTheme-commonJS/classic',
    formatter: ({ dictionary, file }) => {
      const tokenArray = dictionary.allTokens.map((token) =>
        commonJSFormatter({ token, darkTheme: true }),
      );

      return moduleExportFileHeader({ fileHeader, file, tokenArray });
    },
  });

  sd.registerFormat({
    name: 'darkTheme-commonJS/vr-theme',
    formatter: ({ dictionary, file }) => {
      const tokenArray = dictionary.allTokens.map((token) =>
        commonJSFormatter({ token, darkTheme: true, isVR: true }),
      );

      return moduleExportFileHeader({ fileHeader, file, tokenArray });
    },
  });

  sd.registerFormat({
    name: 'constantLibrary-javascript/es6/classic',
    formatter({ dictionary }) {
      const tokenDataString = dictionary.allTokens
        .map((token) => {
          let value = JSON.stringify(token.value);
          if (dictionary.usesReference(token.original.value)) {
            const refs = dictionary.getReferences(token.original.value);
            refs.forEach((ref) => {
              value = value.replace(ref.value, ref.name);
            });
          }

          const formattedTokenName = token.path.join('_').toUpperCase().replace('-', '_');

          return `export const TOKEN_${formattedTokenName} = 'var(--${token.path.join('-')})';`;
        })
        .join(`\n`);

      return `/* File is autogenerated */\n\n${tokenDataString}`;
    },
  });
  sd.registerFormat({
    name: 'constantLibrary-javascript/es6/vr-theme',
    formatter({ dictionary }) {
      const tokenDataString = dictionary.allTokens
        .map((token) => {
          let value = JSON.stringify(token.value);
          if (dictionary.usesReference(token.original.value)) {
            const refs = dictionary.getReferences(token.original.value);
            refs.forEach((ref) => {
              value = value.replace(ref.value, ref.name);
            });
          }

          const formattedTokenNameKey = token.path
            .join('_')
            .toUpperCase()
            .replace('-', '_')
            .replace('appenda', '')
            .replace('appendb', '')
            .replace('APPENDA', '')
            .replace('APPENDB', '');

          const formattedTokenNameValue = token.path
            .join('-')
            .replace('appenda', '')
            .replace('appendb', '');

          return `export const ${formattedTokenNameKey} = 'var(--${formattedTokenNameValue})';`;
        })
        .join(`\n`);

      return `/* File is autogenerated */\n\n${tokenDataString}`;
    },
  });

  sd.registerFormat({
    name: 'constantLibrary-commonJS/classic',
    formatter({ dictionary, file }) {
      const tokens = dictionary.allTokens
        .map((token) => {
          let value = JSON.stringify(token.value);
          if (dictionary.usesReference(token.original.value)) {
            const refs = dictionary.getReferences(token.original.value);
            refs.forEach((ref) => {
              value = value.replace(ref.value, ref.name);
            });
          }
          return `  TOKEN_${token.path
            .join('_')
            .toUpperCase()
            .replace('-', '_')}: 'var(--${token.path.join('-')})',`;
        })
        .join(`\n`)
        .slice(0, -1);

      const fileHeaderString = fileHeader({
        file,
        commentStyle: 'short',
      });

      return `${fileHeaderString}module.exports = Object.freeze({\n${tokens}\n})`;
    },
  });

  sd.registerFormat({
    name: 'constantLibrary-commonJS/vr-theme',
    formatter({ dictionary, file }) {
      const tokens = dictionary.allTokens
        .map((token) => {
          let value = JSON.stringify(token.value);
          if (dictionary.usesReference(token.original.value)) {
            const refs = dictionary.getReferences(token.original.value);
            refs.forEach((ref) => {
              value = value.replace(ref.value, ref.name);
            });
          }
          return `  ${token.path
            .join('_')
            .toUpperCase()
            .replace('-', '_')}: 'var(--${`${token.path.join('-')}`})',`;
        })
        .join(`\n`)
        .slice(0, -1);

      const fileHeaderString = fileHeader({
        file,
        commentStyle: 'short',
      });

      return `${fileHeaderString}module.exports = Object.freeze({\n${tokens}\n})`;
    },
  });
}

module.exports = { registerWebFormats };
